#include "./gaussianFilter2D.h"
#include "./gaussianFilter1D.h"

// 辅助函数：处理边界外的索引（返回0）
inline double padValue(const vector<vector<double>>& input, int x, int y)
{
    return 0.0;
}

vector<vector<double>> gaussianFilter2D(
    const vector<vector<double>>& input,
    int kernelSize,
    double sigma,
    bool useSeparable // 是否使用可分离卷积优化
)
{
    if (input.empty() || input[0].empty()) {
        return {};
    }

    auto kernel = generateGaussianKernel(kernelSize, sigma);
    int half = kernelSize / 2;
    int rows = input.size();
    int cols = input[0].size();
    vector<vector<double>> output(rows, vector<double>(cols, 0.0));

    if (useSeparable) {
        // 可分离卷积：先水平后垂直（效率更高）
        // 水平方向卷积
        vector<vector<double>> temp(rows, vector<double>(cols, 0.0));
        for (int i = 0; i < rows; ++i) {
            for (int j = 0; j < cols; ++j) {
                double sum = 0.0;
                for (int k = -half; k <= half; ++k) {
                    int idx = j + k;
                    if (idx >= 0 && idx < cols) {
                        sum += input[i][idx] * kernel[k + half];
                    }
                }
                temp[i][j] = sum;
            }
        }
        // 垂直方向卷积
        for (int i = 0; i < rows; ++i) {
            for (int j = 0; j < cols; ++j) {
                double sum = 0.0;
                for (int k = -half; k <= half; ++k) {
                    int idx = i + k;
                    if (idx >= 0 && idx < rows) {
                        sum += temp[idx][j] * kernel[k + half];
                    }
                }
                output[i][j] = sum;
            }
        }
    } else {
        // 标准二维卷积
        for (int i = 0; i < rows; ++i) {
            for (int j = 0; j < cols; ++j) {
                double sum = 0.0;
                for (int x = -half; x <= half; ++x) {
                    for (int y = -half; y <= half; ++y) {
                        int xi = i + x;
                        int yj = j + y;
                        // 边界处理：超出范围的值用0填充
                        double pixel = padValue(input, xi, yj);
                        sum += pixel * kernel[(x + half) * kernelSize + (y + half)];
                    }
                }
                output[i][j] = sum;
            }
        }
    }

    return output;
}
